/*
	main header for accessing the Snowstorm engine

	Author: Aidan Goddard 24/7/14
*/

#ifndef SNOWSTORM_H_INCLUDED
#define SNOWSTORM_H_INCLUDED

#include<Windows.h>
#include<stdint.h>

#ifdef SNOWSTORM_EXPORTS
#define SNOWSTORMDLL_API __declspec(dllexport) 
#else
#define SNOWSTORMDLL_API __declspec(dllimport) 
#endif

// engine access
#define v(x) ev->x

// screen type enum
enum SCREEN_TYPE {WINDOWED, FULLSCREEN, EXCLUSIVE_FULLSCREEN};

// engine data structure
struct ENGINE_VARS
{
	// configuration vars (read on engine start. engine must be restarted in order to re-read these)
	uint32_t window_width;
	uint32_t window_height;
	SCREEN_TYPE screen_type;
	bool minimize_on_lost_focus;
	bool lock_cursor_to_window;
	bool hide_cursor;
	wchar_t *window_title;

	// user input
	uint64_t KEYSTATE[4];
	int mickey_x;
	int mickey_y;
	int mickey_z;
	int screen_x;
	int screen_y;
	float xbox_rx;
	float xbox_ry;
	float xbox_lx;
	float xbox_ly;
	float xbox_rtr;
	float xbox_ltr;

	// frame vars
	float target_FPS;
	float current_FPS;
	float frame_time; // gives the time the previous frame took to render in seconds
	float frame_idle_time; // gives the time in seconds that was spent idling in the previous frame
	bool vsync;

	// global control
	bool engine_running;

};

// engine error states
#define ENGINE_ERROR_FAIL 0;
#define ENGINE_ERROR_SUCCESS 1;

// access to the keystates
#define KEY_PRESSED(x) (ev->KEYSTATE[(x / 64)] & (1ULL << (x % 64)))

// main init & control functions
SNOWSTORMDLL_API ENGINE_VARS *EngineInitialise(); // creates the engine vars stucture and initialises the members to default state
SNOWSTORMDLL_API uint32_t EngineStart(ENGINE_VARS *ev); // starts the engine using the control variables in the initialised structure
SNOWSTORMDLL_API uint32_t EngineStop(); // stops the engine.
SNOWSTORMDLL_API uint32_t EngineFrame(); // performs and renders 1 frame. returns 0 to signal that the rendering should stop

// events
SNOWSTORMDLL_API void RegisterKeyPressEvent(uint8_t virtual_key, void(*event_handler)(void));	// register an event handler for a key pressed event
SNOWSTORMDLL_API void RegisterKeyReleaseEvent(uint8_t virtual_key, void(*event_handler)(void)); // register an event handler for a key released event
SNOWSTORMDLL_API void RegisterKeyHeldEvent(uint8_t virtual_key, void(*event_handler)(void));	// register an event handler for a key held event
SNOWSTORMDLL_API void RegisterWindowCloseEvent(void(*event_handler)(void));						// register an event handler to catch an attempt to close the window

// xbox controller
SNOWSTORMDLL_API void XboxSetVibration(float left_motor, float right_motor);					// set the vibration motor states
SNOWSTORMDLL_API void XboxSetDeadZones(float trigger, float left_stick, float right_stick);		// set the analog input deadzones
#define XBOX_DEADZONE_DEFAULT 1.0f
#define XBOX_DEADZONE_DONT_CHANGE 2.0f

// virual keys
// see http://msdn.microsoft.com/en-gb/library/windows/desktop/dd375731(v=vs.85).aspx (28/7/14) for
// MS virtual key listings
// additional virtual keys are defined below (for xbox 360 controller buttons and such) - all use virtual key values marked as "undefined" in the above MSDN page
#define VK_XBOXDPADUP		0x07
#define VK_XBOXDPADDOWN		0x0E
#define VK_XBOXDPADLEFT		0x0F
#define VK_XBOXDPADRIGHT	0x16
#define VK_XBOXA			0x1A
#define VK_XBOXB			0x3A
#define VK_XBOXX			0x3B
#define VK_XBOXY			0x3C
#define VK_XBOXLB			0x3D
#define VK_XBOXRB			0x3E
#define VK_XBOXSTART		0x3F
#define VK_XBOXBACK			0x40
#define VK_XBOXSELECT		0x40
#define VK_XBOXLT			0x88
#define VK_XBOXRT			0x89



#endif